package com.sunky.rfidapp

import android.content.Intent
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import android.widget.LinearLayout
import android.widget.TextView
import com.rfid.rxobserver.RXObserver
import com.rfid.rxobserver.bean.RXInventoryTag
import com.sunky.db.model.ChiperEquipInfo
import com.sunky.db.model.EquipInfo
import com.sunky.db.util.DBManager
import com.sunky.db.util.getAll
import com.sunky.db.util.getList
import com.sunky.rfidapp.util.CommonUtil
import com.sunky.rfidapp.util.RFIDUtils
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.functions.BiFunction
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_equip_list.*
import kotlinx.android.synthetic.main.layout_title.*
import org.greenrobot.greendao.query.WhereCondition

/**
 * 装备列表
 */
class EquipListActivity : BaseActivity() {
    class ListData(
            var id: Long,
            var type: String?,
            var typeName: String?,
            var unit: String?,
            var serialNo: String?,
            var isOperated: Boolean) {
        override fun toString(): String {
            return "ListData(id=$id, type=$type, typeName=$typeName, unit=$unit, serialNo=$serialNo, isOperated=$isOperated)"
        }
    }

    lateinit var inflater: LayoutInflater
    var data: MutableList<ListData> = mutableListOf()
    var equipList: List<EquipInfo>? = null
    var chipperList: List<ChiperEquipInfo>? = null
    var epcSet = mutableSetOf<String>()//EPC 保存
    private val mInventoryObserver = object : RXObserver() {
        override fun onInventoryTag(tag: RXInventoryTag?) {
            Log.e("RXObserver", "onInventoryTag" + tag?.strEPC)
            try {
                tag?.strEPC?.apply {
                    epcSet.add(this.replace(" ", ""))
                }
            } catch (e: Exception) {
                toast(CommonUtil.logToString(e))
            }

        }

        override fun onInventoryTagEnd(tagEnd: RXInventoryTag.RXInventoryTagEnd) {
            Log.e("RXObserver", "onInventoryTagEnd" + tagEnd.toString())
            Observable.just(epcSet)
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe {
                        try {
                            combineListByRFID()
                            (List.adapter as EquipListActivity.EquipListAdapter).notifyDataSetChanged()
                            epcSet.clear()
                        } catch (e: Exception) {
                            toast(CommonUtil.logToString(e))
                        }
                    }
        }

        override fun onExeCMDStatus(cmd: Byte, status: Byte) {
            Log.e("RXObserver", "onExeCMDStatus $cmd $status")
        }
    }

    override fun getLayoutId(): Int {
        return R.layout.activity_equip_list
    }

    override fun initView() {
        inflater = LayoutInflater.from(this)
        TvTitle.text = "装备点验"
        var textListener = object : TextWatcher {
            override fun beforeTextChanged(var1: CharSequence, var2: Int, var3: Int, var4: Int) {}

            override fun onTextChanged(var1: CharSequence, var2: Int, var3: Int, var4: Int) {}

            override fun afterTextChanged(var1: Editable) {
                if (EtScan.text.isNotEmpty()) {
                    IvClear.visibility = View.VISIBLE
                } else {
                    IvClear.visibility = View.GONE
                }
            }
        }
        EtScan.addTextChangedListener(textListener)
        IvClear.setOnClickListener {
            EtScan.setText("")
        }
        IvQuery.setOnClickListener {
            doSearch()
        }
        List.setOnItemClickListener { adapterView, view, i, l ->
            var intent = Intent(this@EquipListActivity, EquipDetailActivity::class.java)
            var isChiper = data[i].type == "密码装备"
            intent.putExtra("ISCHIPER", isChiper)
            if (isChiper) {
                var find = chipperList?.find { it.id == data[i].id }
                CommonUtil.GlobalStorage["EquipDetailActivity"] = find ?: ChiperEquipInfo()
            } else {
                var find = equipList?.find {
                    it.id == data[i].id
                }
                CommonUtil.GlobalStorage["EquipDetailActivity"] = find ?: EquipInfo()
            }
            startActivityForResult(intent, 0)
        }
        List.adapter = EquipListAdapter()
    }

    override fun initData() {
        RFIDUtils.registerObserver(observer = mInventoryObserver)
        var equipObservable = Observable.create<List<EquipInfo>> {
            it.onNext(DBManager.getInstance().getAll(equipDao)!!)
        }
        var chiperObservable = Observable.create<List<ChiperEquipInfo>> {
            it.onNext(DBManager.getInstance().getAll(chipperDao)!!)
        }
        Observable.zip(equipObservable, chiperObservable, BiFunction<List<EquipInfo>, List<ChiperEquipInfo>, List<ListData>> { t1, t2 ->
            equipList = t1
            chipperList = t2
            data
        }).subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                }, {
                    it.printStackTrace()
                })
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == RESULT_OK) {
            refreshOperateState()
        }
    }

    fun doSearch() {
        combineList()
        (List.adapter as EquipListActivity.EquipListAdapter).notifyDataSetChanged()
    }

    override fun onDestroy() {
        super.onDestroy()
        RFIDUtils.unregisterObserver(mInventoryObserver)
    }

    private fun combineList() {
        data.clear()
        if (EtScan.text.isNotEmpty()) {
            equipList?.filter {
                it.equipName.contains(EtScan.text.toString(), true)
            }?.sortedWith(Comparator { t1, t2 -> t1.id.compareTo(t2.id) })?.forEach {
                data.add(EquipListActivity.ListData(it.id, it.equipTypeName, it.equipName, it.unitName, it.serialNo, false))
            }
            chipperList?.filter {
                it.equipName.contains(EtScan.text.toString(), true)
            }?.sortedWith(Comparator { t1, t2 -> t1.id.compareTo(t2.id) })?.forEach {
                data.add(EquipListActivity.ListData(it.id, it.equipTypeName, it.equipName, it.unitName, it.equipSerialNo, false))
            }
        }
        printData()
        refreshOperateState()
    }

    private fun combineListByRFID() {
        EtScan.setText("")
        data.clear()
        if (epcSet.isNotEmpty()) {
            equipList?.filter {
                epcSet.contains(it.codeInfo)
            }?.sortedWith(Comparator { t1, t2 -> t1.id.compareTo(t2.id) })?.forEach {
                data.add(EquipListActivity.ListData(it.id, it.equipTypeName, it.equipName, it.unitName, it.serialNo, false))
            }
            chipperList?.filter {
                epcSet.contains(it.codeinfo)
            }?.sortedWith(Comparator { t1, t2 -> t1.id.compareTo(t2.id) })?.forEach {
                data.add(EquipListActivity.ListData(it.id, it.equipTypeName, it.equipName, it.unitName, it.equipSerialNo, false))
            }
        }
        refreshOperateState()
    }

    private fun refreshOperateState() {
        Observable.create<MutableList<ListData>> {
            for ((index, mData) in data.withIndex()) {
                var checkRecord = DBManager.getInstance().getList(checkRecordDao, WhereCondition.StringCondition("_id = ?", mData.id))
                if (checkRecord != null && checkRecord.isNotEmpty()) {
                    data[index].isOperated = true
                }
            }
            it.onNext(data)
        }.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe {
                    (List.adapter as EquipListActivity.EquipListAdapter).notifyDataSetChanged()
                }
    }

    private fun printData() {
//        for(mData in data){
//            Log.e("RESULT",mData.toString())
//        }
    }

    inner class EquipListAdapter : BaseAdapter() {
        override fun getView(p0: Int, p1: View?, p2: ViewGroup?): View {
            var view: View
            var holder = if (p1 == null) {
                view = inflater.inflate(R.layout.item_check, p2, false)
                ViewHolderEquipList(view)
            } else {
                view = p1
                p1.tag as ViewHolderEquipList
            }
            var thisData = data[p0]
            holder.TvType.text = thisData.type/* + "   "+thisData.id*/
            holder.TvName.text = thisData.typeName
            holder.TvUnit.text = thisData.unit
            holder.TvSerialNo.text = thisData.serialNo
            if (thisData.isOperated) {
                holder.Bg.setBackgroundResource(R.drawable.shape_gray_item_bg)
            } else {
                holder.Bg.setBackgroundResource(R.drawable.shape_item_bg)
            }
            return view
        }

        override fun getItem(p0: Int): Any {
            return data[p0]
        }

        override fun getItemId(p0: Int): Long {
            return p0.toLong()
        }

        override fun getCount(): Int {
            return data.size
        }


    }

    class ViewHolderEquipList {
        var Bg: LinearLayout
        var TvType: TextView
        var TvName: TextView
        var TvUnit: TextView
        var TvSerialNo: TextView
        var TvCheckDetail: TextView

        constructor(view: View) {
            Bg = view.findViewById(R.id.Bg)
            TvType = view.findViewById(R.id.TvDeviceType)
            TvName = view.findViewById(R.id.TvName)
            TvUnit = view.findViewById(R.id.TvUnit)
            TvSerialNo = view.findViewById(R.id.TvNo)
            TvCheckDetail = view.findViewById(R.id.TvCheckDetail)
            view.tag = this
        }
    }
}